/*
 * Copyright (c) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License,Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.harmonyos.studyharmonyos.slice;

import com.harmonyos.studyharmonyos.ResourceTable;
import com.harmonyos.studyharmonyos.bean.MailDataBean;
import com.harmonyos.studyharmonyos.helper.DeviceSelectDialog;
import com.harmonyos.studyharmonyos.helper.WidgetHelper;
import com.harmonyos.studyharmonyos.helper.listcomponent.CommentViewHolder;
import com.harmonyos.studyharmonyos.helper.listcomponent.ListComponentAdapter;
import com.harmonyos.studyharmonyos.util.DeviceUtils;
import com.harmonyos.studyharmonyos.util.LogUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.ability.IAbilityContinuation;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.agp.components.*;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.app.Context;
import ohos.data.resultset.ResultSet;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;
import ohos.media.image.ImageSource;
import ohos.media.photokit.metadata.AVStorage;
import ohos.utils.net.Uri;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_PARENT;

/**
 * Mail edit slice
 *
 * @since 2021-02-04
 */
public class MailEditSlice extends AbilitySlice implements IAbilityContinuation {
    private static final String TAG = MailEditSlice.class.getSimpleName();
    private static final int CACHE_SIZE = 8 * 1024;
    private static final int IO_END_LEN = -1;
    private static final int TIPS_DURATION_TIME = 50;

    private TextField receiver;
    private TextField cc;
    private TextField title;
    private TextField content;
    private Image doConnectImg;
    private Button btnHuiqian;

    private final List<String> mDialogDataList = new ArrayList<>();//分布式数据地址列表
    private ListComponentAdapter mRecycleItemProvider;//邮件对话框附件列表适配器
    private CommonDialog fileDialog;
    private final List<String> mAttachmentDataList = new ArrayList<>();//已选择的附件数据
    private ListComponentAdapter mAttachmentProvider;//附件列表适配器

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        LogUtils.info(TAG, "is onStart begin");
        Component view = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_moudle_mail_edit, null, false);
        ComponentContainer rootLayout;
        if (!(view instanceof ComponentContainer)) {
            rootLayout = new DirectionalLayout(this);
        } else {
            adaptView(view);
            setClickAction(view);
            rootLayout = (ComponentContainer) view;
        }
        super.setUIContent(rootLayout);
        LogUtils.info(TAG, "is onStart end");
    }

    private void adaptView(Component rootView) {
        Component view = rootView.findComponentById(ResourceTable.Id_mail_edit_receiver);
        if (view instanceof TextField) {
            receiver = (TextField) view;
        }
        view = rootView.findComponentById(ResourceTable.Id_mail_edit_cc);
        if (view instanceof TextField) {
            cc = (TextField) view;
        }
        view = rootView.findComponentById(ResourceTable.Id_mail_edit_title);
        if (view instanceof TextField) {
            title = (TextField) view;
        }
        doConnectImg = (Image) rootView.findComponentById(ResourceTable.Id_mail_edit_continue);
        view = rootView.findComponentById(ResourceTable.Id_mail_edit_content);
        if (view instanceof TextField) {
            content = (TextField) view;
        }
        btnHuiqian = (Button) rootView.findComponentById(ResourceTable.Id_btn_huiqian);
        // 初始化界面
        fillView();
        setAttachmentProvider(rootView);
        rootView.findComponentById(ResourceTable.Id_btn_huiqian).setClickedListener(listener -> {
            try {
                reverseContinueAbility();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
        });
    }

    //构建附件列表
    private void setAttachmentProvider(Component rootView) {
        ListContainer mAttachmentContainer = (ListContainer) rootView.findComponentById(ResourceTable.Id_attachment_list);
        mAttachmentProvider =
                new ListComponentAdapter<String>(
                        getContext(), mAttachmentDataList, ResourceTable.Layout_attachment_item_horizontal) {
                    @Override
                    public void onBindViewHolder(CommentViewHolder commonViewHolder, String item, int position) {
                        commonViewHolder
                                .getTextView(ResourceTable.Id_item_title1)
                                .setText(item.substring(item.lastIndexOf(File.separator) + 1));
                        FileInputStream fileInputStream = null;
                        try {
                            fileInputStream = new FileInputStream(item);
                            ImageSource source = ImageSource.create(fileInputStream, null);
                            commonViewHolder
                                    .getImageView(ResourceTable.Id_image)
                                    .setPixelMap(source.createPixelmap(0, null));
                        } catch (FileNotFoundException e) {
                            LogUtils.error(TAG, "setAttachmentProvider Error");
                        } finally {
                            try {
                                fileInputStream.close();
                            } catch (IOException e) {
                                LogUtils.error(TAG, "close fileInputStream Error");
                            }
                        }
                    }
                };
        mAttachmentContainer.setItemProvider(mAttachmentProvider);
    }

    //初始化数据
    private void fillView() {
        if (cachedMailData == null) {
            receiver.setText("user1;user2");//初始化默认收件人
            cc.setText("user3");//初始化默认抄送人员
            title.setText("RE：HarmonyOS 2.0 体验");//初始化主题
        } else {
            receiver.setText(cachedMailData.getReceiver());
            cc.setText(cachedMailData.getCc());
            title.setText(cachedMailData.getTitle());
            content.setText(cachedMailData.getContent());
            if (cachedMailData.getPictureDataList().size() > 0) {
                // 清空现有数据，并刷新
                mAttachmentDataList.clear();
                mAttachmentDataList.addAll(cachedMailData.getPictureDataList());
            }
        }
    }

    //迁移与选择附件
    private void setClickAction(Component rootView) {
        //迁移
        doConnectImg.setClickedListener(
                clickedView -> {
                    // 通过FLAG_GET_ONLINE_DEVICE标记获得在线设备列表
                    List<DeviceInfo> deviceInfoList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
                    if (deviceInfoList.size() > 0) {//如果存在在网设备
                        DeviceSelectDialog dialog = new DeviceSelectDialog(this);
                        //赋值回调函数，点击确定后迁移到指定设备
                        dialog.setListener(
                                deviceInfo -> {
                                    LogUtils.debug(TAG, "deviceName  ===  " + deviceInfo.getDeviceName());
                                    try {
                                        // 开始任务迁移
//                                        continueAbility();
                                        continueAbilityReversibly();
                                        btnHuiqian.setText("回迁");
                                    } catch (IllegalStateException | UnsupportedOperationException e) {
                                        WidgetHelper.showTips(this, ResourceTable.String_tips_mail_continue_failed);
                                    }
                                    dialog.hide();
                                });
                        dialog.show();
                    } else {
                        WidgetHelper.showTips(this, "无在网设备");
                    }
                });
        //选择主题图片
        rootView.findComponentById(ResourceTable.Id_open_dir)
                .setClickedListener(
                        c -> {
                            // 如果fileDialog不为空且已显示，则退出，防止多次点击一直弹窗
                            if (fileDialog != null && fileDialog.isShowing()) {
                                return;
                            }
                            //清空数据列表
                            mDialogDataList.clear();
                            // 获取分布式服务目录下文件地址列表
                            List<String> tempListRemotes = DeviceUtils.getFile(this);
                            mDialogDataList.addAll(tempListRemotes);
                            // 弹窗邮件附件选择框
                            showDialog(getContext());
                        });
    }

    // 弹出邮件附件选择框
    public void showDialog(Context context) {
        Component rootView = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_picture, null, false);
        ListContainer listContainer = (ListContainer) rootView.findComponentById(ResourceTable.Id_list_container_pic);
        if (mRecycleItemProvider == null) {//适配器为空，则创建
            mRecycleItemProvider = new ListComponentAdapter<String>(getContext(), mDialogDataList, ResourceTable.Layout_dialog_picture_item) {//创建列表显示适配器
                @Override
                public void onBindViewHolder(CommentViewHolder commonViewHolder, String url, int position) {
                    //文件名称
                    commonViewHolder.getTextView(ResourceTable.Id_item_desc).setText(url.substring(url.lastIndexOf(File.separator) + 1));
                    FileInputStream fileInputStream = null;
                    try {
                        fileInputStream = new FileInputStream(url);
                        ImageSource source = ImageSource.create(fileInputStream, null);
                        //显示图片
                        commonViewHolder.getImageView(ResourceTable.Id_image).setPixelMap(source.createPixelmap(0, null));
                    } catch (FileNotFoundException e) {
                        LogUtils.error(TAG, "showDialog() FileNotFound Exception");
                    } finally {
                        try {
                            fileInputStream.close();
                        } catch (IOException e) {
                            LogUtils.error(TAG, "close fileInputStream error");
                        }
                    }
                }
            };
        } else {//不为空，则直接刷新适配器
            mRecycleItemProvider.notifyDataChanged();
        }
        clickOnAttachment(listContainer);
        fileDialog = new CommonDialog(context);//声明弹出框
        fileDialog.setSize(MATCH_PARENT, MATCH_PARENT);//设置弹窗大小
        fileDialog.setAlignment(LayoutAlignment.BOTTOM);//设置弹框位置为居下
        fileDialog.setAutoClosable(true);//设置可自动关闭
        fileDialog.setContentCustomComponent(rootView);//绑定自定义布局
        fileDialog.show();//显示弹窗
    }

    /* 点击选择附件*/
    private void clickOnAttachment(ListContainer listContainer) {
        listContainer.setItemProvider(mRecycleItemProvider);//绑定显示适配器
        listContainer.setItemClickedListener((listContainer1, component, i, l) -> {
            if (mAttachmentDataList.contains(mDialogDataList.get(i))) {//已选择附件数组已存在该记录
                WidgetHelper.showTips(this, "此附件已添加！", TIPS_DURATION_TIME);
            } else {
                mAttachmentDataList.add(mDialogDataList.get(i));//不存在，则加入已选择附件数组
                mAttachmentProvider.notifyDataChanged();//刷新页面适配器
                fileDialog.destroy();//关闭弹框
            }
        });
    }
    //分布式图片文件
    public void initPublicPictureFile(Context context) {
        /* 查找本机所有图片，并加入分布式文件系统 */
        DataAbilityHelper helper = DataAbilityHelper.creator(context);
        InputStream in = null;
        OutputStream out = null;
        String[] projections =
                new String[]{
                        AVStorage.Images.Media.ID, AVStorage.Images.Media.DISPLAY_NAME, AVStorage.Images.Media.DATA
                };
        try {
            ResultSet results = helper.query(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, projections, null);
            while (results != null && results.goToNextRow()) {
                int mediaId = results.getInt(results.getColumnIndexForName(AVStorage.Images.Media.ID));//获取数据ID
                String fullFileName = results.getString(results.getColumnIndexForName(AVStorage.Images.Media.DATA));//获取存储媒体数据的文件系统中的绝对路径。
                String fileName = fullFileName.substring(fullFileName.lastIndexOf(File.separator) + 1);//截取文件名称
                Uri contentUri = Uri.appendEncodedPathToUri(AVStorage.Images.Media.EXTERNAL_DATA_ABILITY_URI, "" + mediaId);//转换Uri地址格式
                /*
                 * 只读模式打开Uri地址 "r" 表示只读访问 "w" 表示只写访问 "wt" 表示截断任何现有文件的写访问
                 * "wa" 用于附加到任何现有数据的只写访问 "rw" 用于任何现有数据的读写访问 "rwt" 用于截断任何现有文件的读写访问
                 */
                FileDescriptor fileDescriptor = helper.openFile(contentUri, "r");
                if (getDistributedDir() == null) {
                    WidgetHelper.showTips(this, "注意：分布式文件异常！", TIPS_DURATION_TIME);
                    return;
                }
                String distributedFilePath = getContext().getDistributedDir().getPath() + File.separator + fileName;//分布式目录保存地址
                File fr = new File(distributedFilePath);
                in = new FileInputStream(fileDescriptor);
                out = new FileOutputStream(fr);
                byte[] buffers = new byte[CACHE_SIZE];
                int count = 0;
                while ((count = in.read(buffers)) != IO_END_LEN) {
                    out.write(buffers, 0, count);
                }
                out.close();
                LogUtils.info(TAG, "STOP WRITING");
            }
        } catch (DataAbilityRemoteException | IOException e) {
            LogUtils.error(TAG, "initPublicPictureFile exception");
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                LogUtils.error(TAG, "io exception");
            }
        }
    }

    //是否可迁移
    @Override
    public boolean onStartContinuation() {
        LogUtils.info(TAG, "onStartContinuation ");
        return true;
    }

    private MailDataBean cachedMailData;

    //保存数据
    @Override
    public boolean onSaveData(IntentParams params) {
        LogUtils.info(TAG, "onSaveData  保存数据");
        MailDataBean mailData = getMailData();
        mailData.saveDataToParams(params);
        return true;
    }

    //恢复数据
    @Override
    public boolean onRestoreData(IntentParams params) {
        LogUtils.info(TAG, "onRestoreData  恢复数据");
        cachedMailData = new MailDataBean(params);
        return true;
    }

    //迁移完成
    @Override
    public void onCompleteContinuation(int state) {
        LogUtils.info(TAG, "onCompleteContinuation  迁移完成 = " + state);
//        terminateAbility();//关闭当前页
    }

    @Override
    public void onRemoteTerminated() {
        LogUtils.info(TAG, "onRemoteTerminated  目标侧异常");
        btnHuiqian.setText("下一步");
    }

    private MailDataBean getMailData() {
        MailDataBean data = new MailDataBean();
        data.setReceiver(receiver.getText());
        data.setCc(cc.getText());
        data.setTitle(title.getText());
        data.setContent(content.getText());
        data.setPictureDataList(mAttachmentDataList);
        return data;
    }

    @Override
    protected void onActive() {
        super.onActive();
        LogUtils.info(TAG, "is onActive begin");
        initPublicPictureFile(this);
        LogUtils.info(TAG, "is onActive end");
    }

    @Override
    protected void onStop() {
        super.onStop();
        LogUtils.info(TAG, "is onStop");
    }
}
